package com.itheima.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.itheima.constant.MessageConstant;
import com.itheima.constant.RedisConstant;
import com.itheima.constant.RedisMessageConstant;
import com.itheima.entity.PageResult;
import com.itheima.entity.QueryPageBean;
import com.itheima.entity.Result;
import com.itheima.pojo.Menu;
import com.itheima.pojo.Role;
import com.itheima.service.UserService;
import com.itheima.utils.QiniuUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

@RestController
@RequestMapping("/user")
public class UserController {

    @Reference
    private UserService userService;

    @Autowired
    private JedisPool jedisPool;

    //密码加密对象
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    //获取当前登录（认证）用户的用户名
    @RequestMapping("/getLoginUsername.do")
    public Result getLoginUsername() {
        try {
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            return new Result(true, MessageConstant.GET_USERNAME_SUCCESS, user.getUsername());
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_USERNAME_FAIL);
        }
    }

    //获取当前登录（认证）用户的头像
    @RequestMapping("/getAvatar.do")
    public Result getAvatar() {
        try {
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            //获取头像

            return new Result(true, MessageConstant.GET_USERNAME_SUCCESS, user.getUsername());
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_USERNAME_FAIL);
        }
    }

    //获取当前登录用户的菜单
    @RequestMapping("/getMenuListByUsername.do")
    public Result getMenuListByUsername() {
        try {
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            LinkedHashSet<Menu> menus = userService.getMenuListByUsername(user.getUsername());
            return new Result(true, MessageConstant.GET_MENU_SUCCESS, menus);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_MENU_FAIL);
        }
    }

    //获取当前登录用户的头像
    @RequestMapping("/getAvatarByUsername.do")
    public Result getAvatarByUsername() {
        try {
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            String avatar = userService.getAvatarByUsername(user.getUsername());
            return new Result(true, MessageConstant.GET_AVA_SUCCESS, avatar);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.GET_AVA_SUCCESS);
        }
    }

    //获取当前登录用户的头像
    @RequestMapping("/chgAvatar.do")
    public Result chgAvatar(@RequestBody Map map) {
        try {
            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
            userService.chgAvatarByUsername(user.getUsername(),(String) map.get("avatar"));
            return new Result(true, MessageConstant.CHG_AVA_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.CHG_AVA_FAIL);
        }
    }

    @RequestMapping("/chgpwd.do")
    public Result changePwd(HttpServletResponse response, @RequestBody Map map) {
        String telephone = (String) map.get("telephone");
        String validateCode = (String) map.get("validateCode");
        String password = passwordEncoder.encode((String) map.get("password"));
        try {
            Jedis resource = jedisPool.getResource();
            String validateCodeInRedis = resource.get(telephone + RedisMessageConstant.SENDTYPE_GETPWD); //获取redis验证码
            System.out.println(validateCodeInRedis);
            String countStr = resource.get(telephone + RedisMessageConstant.SENDTYPE_COUNT);       //获取验证码可用次数
            if (validateCode != null && validateCodeInRedis != null && countStr != null
                    && validateCode.equals(validateCodeInRedis) && Integer.parseInt(countStr) > 0) {
                //看看用户是否存在
                com.itheima.pojo.User user = userService.findByTelephone(telephone);
                //不存在
                if (user == null) {
                    return new Result(false, MessageConstant.USER_DEXIST);
                }
                //修改密码操作
                userService.changPwd(telephone, password);
                //删除redis集合中的数据
                resource.del(telephone + RedisMessageConstant.SENDTYPE_COUNT);
                resource.del(telephone + RedisMessageConstant.SENDTYPE_GETPWD);
                //释放资源
                resource.close();
                //修改成功
                return new Result(true, MessageConstant.CHGPWD_SUCCESS);
            } else {
                //判断redis telephone+"000" 是否存在 存在 返回result  附带信息 "验证码尝试次数过多,请稍后再试"  附带返回数据false
                String disableStatus = resource.get(telephone + "000");
                if (disableStatus != null && disableStatus.equals("000")){
                    return new Result(false,"验证码尝试次数过多,请稍后再试");
                }
                //如果验证码还有验证次数  验证码校验次数减一
                if (countStr != null) {
                    Integer count = Integer.parseInt(countStr);
                    if (count > 0) {
                        resource.setex(telephone + RedisMessageConstant.SENDTYPE_COUNT, 300, String.valueOf(count - 1));
                    }
                    //判断验证次数count是否为0  为0 设置一个禁用redis telephone+"000"  时间5分钟
                    if (count == 0){
                        resource.setex(telephone + "000", 300, "000");
                    }
                }
                resource.close();
                //验证码错误
                return new Result(false, MessageConstant.VALIDATECODE_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            //登录出错
            return new Result(false, MessageConstant.CHGPWD_FAIL);
        }
    }

    @RequestMapping("/uploadAvatar.do")
    public Result upload(@RequestParam("imgFile") MultipartFile multipartFile) {
        Jedis resource = null;
        try {
            resource = jedisPool.getResource();       //获取jedis池的资源
            String originalFilename = multipartFile.getOriginalFilename(); //获取源文件名
            String extension = originalFilename.substring(originalFilename.lastIndexOf(".") - 1);   //获取文件扩展名{
            String fileName = UUID.randomUUID().toString() + extension;     //生成文件名
            //上传文件到七牛云
            QiniuUtils.upload2Qiniu(multipartFile.getBytes(), fileName);
            //将有的文件数据保存到redis 这里只是上传完成 不存为数据库的资源
            resource.sadd(RedisConstant.SETMEAL_PIC_RESOURCES, fileName);
            return new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS, fileName);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.PIC_UPLOAD_FAIL);
        } finally {
            //释放资源
            if (resource != null) {
                resource.close();
            }
        }
    }

    //分页遍历&模糊查询用户信息
    @RequestMapping("/findPage.do")
    @PreAuthorize("hasAuthority('USER_QUERY')")
    public PageResult findPage(@RequestBody QueryPageBean queryPageBean){
        return userService.findPage(queryPageBean);
    }

    //新增用户
    @RequestMapping("/add.do")
    @PreAuthorize("hasAuthority('USER_ADD')")
    public Result add(Integer[] roleIds,@RequestBody com.itheima.pojo.User user){
        try{
            //BCrypt方式对用户密码加密
            String saltCode = passwordEncoder.encode(user.getPassword());
            user.setPassword(saltCode);
            userService.add(roleIds,user);
            return new Result(true,"新增用户成功");
        }catch (Exception e){
            return new Result(false,"新增用户失败");
        }
    }

    //根据id查找用户(编辑回显)
    @RequestMapping("/findByUserId")
    public Result findByUserId(Integer id){
        try{
            com.itheima.pojo.User user=userService.findByUserId(id);
            return new Result(true,"查询用户成功",user);
        }catch (Exception e){
            e.printStackTrace();
            return new Result(false,"查询用户失败");
        }
    }

    //根据用户id查找其对应的角色
    @RequestMapping("/findRoleByUserId")
    public Result findRoleByUserId(Integer id){
        try{
            List<Role> rolelist=userService.findRoleByUserId(id);
            List<Integer> list=new ArrayList<>();
            for (Role role : rolelist) {
                Integer roleId = role.getId();
                list.add(roleId);
            }
            return new Result(true,"查询用户角色成功",list);
        }catch (Exception e){
            e.printStackTrace();
            return new Result(false,"查询用户角色失败");
        }
    }

    //编辑用户
    @RequestMapping("/update")
    @PreAuthorize("hasAuthority('USER_EDIT')")
    public Result update(Integer[] roleIds, @RequestBody com.itheima.pojo.User user){
        String password = user.getPassword();
        if (password!=null&&password.length()>0){
            //用户密码加盐加密
            user.setPassword(passwordEncoder.encode(password));
        }
        try{
            userService.edit(roleIds,user);
            return new Result(true,"编辑用户成功");
        }catch (Exception e){
            //编辑用户信息失败
            e.printStackTrace();
            return new Result(false,"编辑用户失败");
        }
    }

    //删除用户
    @RequestMapping("/delete")
    @PreAuthorize("hasAuthority('USER_DELETE')")
    public Result delete(Integer id){
        try{
            userService.delete(id);
            return new Result(true,"删除用户成功");
        }catch (Exception e){
            e.printStackTrace();
            return new Result(false,"删除用户失败");
        }
    }

    //修改用户状态(开启/关闭)
    @RequestMapping("/updateStation")
    public Result updateStation(Integer id,String station){
            return userService.updateStation(id,station);
    }
}
